package users;

import info.Conference;
import info.Manuscript;

import java.util.LinkedList;
import java.util.List;

import ui.MainPage;
import ui.Standards;

/**
 * The Subprogram Chair class is modeled after the functions and
 * responsibilities that a Subprogram Chair will have.  The
 * Subprogram Chair is responsible for organizing their connections
 * with Reviewers; volunteers who are generally experts of the
 * field that the Subprogram Chair specializes in.  In addition,
 * the Subprogram Chair takes a look at the reviews that each
 * manuscript receives and makes a recommendation to the Program
 * Chair based on the reviews and his opinion.
 * @author Aaron Chen
 * @version 3/21/2014
 */
public class SubprogramChair extends AbstractRole {
  
  /** The ID that this role is represented by. */
  public static final int ROLE_ID = 2;
  
  /** The name of this role. */
  public static final String ROLE_NAME = "Subprogram Chair";

  /** The Program Chair that the Subprogram Chair responds to. */
  private long my_program_chair;

  /** The categories of the conference that the Subprogram Chair
   * is assigned to specialize in. */
  private List<String> my_categories;

  /** The list of reviewers that are responsible to the Subprogram
   * Chair. */
  private List<Long> my_reviewers;

  /** The list of manuscripts that the Subprogram Chair is responsible
   * for reviewing. */
  private List<Long> my_manuscripts;


  /**
   * Constructs a new Subprogram Chair role.
   * @param the_user The user that this role belongs to.
   * @param the_conference The conference that this role belongs to.
   * @param the_program_chair The Program Chair that the Subprogram Chair
   * responds to.
   */
  public SubprogramChair(final User the_user,
                         final Conference the_conference,
                         final ProgramChair the_program_chair) {
    super(0, the_user.getID(), the_conference.getID());
    my_program_chair = the_program_chair.getUserID();
    my_reviewers = new LinkedList<Long>();
    my_manuscripts = new LinkedList<Long>();
  }
  
  /**
   * Constructs a new Subprogram Chair role.
   * @param the_role_id The ID for this particular role assignment.
   * @param the_user_id The user that this role belongs to.
   * @param the_conference_id The conference that this role belongs to.
   * @param the_program_chair_id The Program Chair that the Subprogram Chair
   * @param the_reviewer_ids The list of Reviewers that respond to this SPC.
   * @param the_manuscript_ids The list of Manuscripts.
   * responds to.
   */
  public SubprogramChair(final long the_role_id,
                         final long the_user_id,
                         final long the_conference_id,
                         final long the_program_chair_id,
                         final List<Long> the_reviewer_ids,
                         final List<Long> the_manuscript_ids) {
    super(the_role_id, the_user_id, the_conference_id);
    my_program_chair = the_program_chair_id;
    my_reviewers = the_reviewer_ids;
    my_manuscripts = the_manuscript_ids;
  }

  /**
   * Assigns a Reviewer role to a user that the Subprogram Chair trusts.
   * @param the_user The user to be assigned as a Reviewer.
   * @return true if the user was successfully assigned a Reviewer role;
   * false otherwise.
   */
  public boolean assignReviewerRole(final User the_user) {
    final List<Role> roles = the_user.getRoles();
    final Role pc = MainPage.getDatabase().accessRole().getRole(my_program_chair);
    for (Role role : roles) {
      if (role.getRoleID() == Standards.ROLE_ID_REVIEWER
          && role.getConferenceID() == pc.getConferenceID()) {
        return false;
      }
    }
    final Conference conf =
        MainPage.getDatabase().accessConf().getConference(this.getConferenceID());
    final Reviewer rev = new Reviewer(the_user, conf, this.getID());
    the_user.addRole(rev);
    my_reviewers.add(rev.getID());
    MainPage.getDatabase().accessRole().editRole(this);
    return true;
  }

  /**
   * Assigns a manuscript to a Reviewer for reviewing.  A Reviewer may
   * only have a limited number of manuscripts to review.
   * @param the_manuscript The manuscript to be assigned.
   * @param the_reviewer The Reviewer to receive the manuscript assignment.
   * @return true if the manuscript was assigned successfully to the
   * Reviewer; false otherwise.
   */
  public boolean assignManuscriptToReviewer(final Manuscript the_manuscript,
                                            final Reviewer the_reviewer) {
    //TODO assignManuscriptToReviewer
    return false;
  }

  /** 
   * Adds a new manuscript to the Program Chair's responsibilities.
   * @param the_manu_id The ID of the manuscript.
   */
  public void assignManuscript(final long the_manu_id) {
    my_manuscripts.add(the_manu_id);
  }

  /**
   * Returns the ID of the Program Chair that this Subprogram Chair has been
   * assigned under.
   * @return The ID of the Program Chair.
   */
  public long getProgramChair() {
    return my_program_chair;
  }

  /**
   * Returns the list of categories that the Subprogram Chair has been assigned
   * under.
   * @return The list of categories.
   */
  public List<String> getCategories() {
    return my_categories;
  }

  /**
   * Returns the list of Reviewers that work under the Subprogram Chair.
   * @return The list of Reviewers.
   */
  public List<Long> getReviewers() {
    return my_reviewers;
  }

  /**
   * Returns the list of Manuscripts that have been assigned to this Subprogram
   * Chair.
   * @return The list of Manuscripts.
   */
  public List<Long> getManuscripts() {
    return my_manuscripts;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public int getRoleID() {
    return ROLE_ID;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public String getRoleName() {
    return ROLE_NAME;
  }
  
  /**
   * {@inheritDoc}
   */
  @Override
  public String toString() {
    return ROLE_NAME;
  }
  
}
